package member

import (
	"errors"
	"lao-a/helper"
	"lao-a/models"
	"lao-a/models/model"
	"strconv"
	"strings"
	"time"
)

const (
	CARD_PERSONAL   = "personal"
	CARD_ENTERPRISE = "enterprise"

	CARD_PERSONAL_PREFIX   = "P-"
	CARD_ENTERPRISE_PREFIX = "E-"

	CARD_SEQNAME_PERSONAL   = "ta_card_personal"
	CARD_SEQNAME_ENTERPRISE = "ta_card_enterprise"
)

const (
	CARD_STATUS_NORMAL = 1
)

// 会员卡类型
func (m *DAO) GetCardTypes() []CommonType {
	return []CommonType{
		CommonType{
			TypeId:   CARD_PERSONAL,
			TypeName: "个人",
		},
		CommonType{
			TypeId:   CARD_ENTERPRISE,
			TypeName: "企业",
		},
	}
}

// SaveCard 保存会员卡
func (m *DAO) SaveCard(card *model.TaCard, cardType string) (*model.TaCard, error) {
	_, err := m.db.Insert(card)

	// 卡号进一
	if cardType == CARD_PERSONAL {
		models.Nextval(CARD_SEQNAME_PERSONAL)
	} else {
		models.Nextval(CARD_SEQNAME_ENTERPRISE)
	}

	return card, err
}

// InitCard 初始化会员卡
func (m *DAO) InitCard(cardNum string, cardType string) (*model.TaCard, error) {
	user := m.ctx.User.(*model.SysUser)
	now := time.Now()

	// 先注册会员卡
	if has, err := m.DoesCardNumExist(cardNum); err != nil {
		return nil, err
	} else {
		if has {
			return nil, helper.LogError("初始化会员失败, 卡号已存在")
		}
	}

	card := &model.TaCard{
		CardNum:    cardNum,
		Status:     CARD_STATUS_NORMAL,
		CreateUser: user.UserId,
		CreateDate: now,
	}

	return m.SaveCard(card, cardType)
}

// DoesCardNumExist 验证卡号是否已经存在
func (m *DAO) DoesCardNumExist(cardNum string) (bool, error) {
	cnt, err := m.db.Where("card_num=?", cardNum).Count(&model.TaCard{})
	if err != nil {
		return false, helper.LogError("验证卡号是否已经存在失败", err)
	}

	return cnt > 0, nil
}

// GetNewCardNum 获取最新未分配卡号
func (m *DAO) GetNewCardNum(cardType string) (string, error) {
	minLen := 6
	prefix := CARD_PERSONAL_PREFIX
	seqName := CARD_SEQNAME_PERSONAL

	if cardType == CARD_ENTERPRISE {
		prefix = CARD_ENTERPRISE_PREFIX
		seqName = CARD_SEQNAME_ENTERPRISE
	}

	curVal := models.Currval(seqName)
	if curVal < 1 {
		return "", errors.New("获取最新卡号失败")
	}

	nextVal := curVal + 1
	if len(strconv.Itoa(nextVal)) > minLen {
		return "", errors.New("系统内置卡号已分配完毕")
	}

	cardNo := strconv.Itoa(curVal)

	return prefix + strings.Repeat("0", minLen-len(cardNo)) + cardNo, nil
}
